Option Strict Off
Option Explicit On
Module mod_basConvert

    ' basConvert: Utilities to convert between byte arrays, hex strings,
    ' strings containing binary values, and 32-bit word arrays.

    ' Version 1. Published January 2002
    '************************* COPYRIGHT NOTICE*************************
    ' This code was originally written in Visual Basic by David Ireland
    ' and is copyright (c) 2000-2 D.I. Management Services Pty Limited,
    ' all rights reserved.

    ' You are free to use this code as part of your own applications
    ' provided you keep this copyright notice intact.

    ' This code may only be used as part of an application. It may
    ' not be reproduced or distributed separately by any means without
    ' the express written permission of the author.

    ' David Ireland and DI Management Services Pty Limited make no
    ' representations concerning either the merchantability of this
    ' software or the suitability of this software for any particular
    ' purpose. It is provided "as is" without express or implied
    ' warranty of any kind.

    ' Please forward comments or bug reports to <code@di-mgt.com.au>.
    ' The latest version of this source code can be downloaded from
    ' www.di-mgt.com.au/crypto.html.
    '****************** END OF COPYRIGHT NOTICE*************************

    ' The friend Functions in this module are:
    ' cv_BytesFromHex(sInputHex): Returns array of bytes
    ' cv_BytesFromString(strInput): Returns array of bytes
    ' cv_WordsFromHex(sHex): Returns array of words (Longs)
    ' cv_HexFromWords(aWords): Returns hex string
    ' cv_HexFromBytes(aBytes()): Returns hex string
    ' cv_HexFromString(str): Returns hex string
    ' cv_StringFromHex(strHex): Returns string of ascii characters
    ' cv_GetHexByte(sInputHex, iIndex): Extracts iIndex'th byte from hex string
    ' RandHexByte(): Returns random byte as a 2-digit hex string
    Friend Function cv_BytesFromHex(ByVal sInputHex As Byte()) As Byte()
        Dim i As Integer
        Dim M As Integer
        Dim aBytes() As Byte
        'If Len(sInputHex) Mod 2 <> 0 Then
        '    sInputHex = "0" & sInputHex
        'End If

        M = sInputHex.Length \ 2
        ReDim aBytes(M - 1)

        For i = 0 To M - 1
            aBytes(i) = Val("&H" & Chr(sInputHex(i * 2)) & Chr(sInputHex(i * 2 + 1)))
        Next

        Return aBytes
    End Function
    Friend Function cv_BytesFromHex(ByVal sInputHex As String) As Byte()
        ' Returns array of bytes from hex string in big-endian order
        ' E.g. sHex="FEDC80" will return array {&HFE, &HDC, &H80}
        Dim i As Integer
        Dim M As Integer
        Dim aBytes() As Byte
        If Len(sInputHex) Mod 2 <> 0 Then
            sInputHex = "0" & sInputHex
        End If

        M = Len(sInputHex) \ 2
        ReDim aBytes(M - 1)

        For i = 0 To M - 1
            aBytes(i) = Val("&H" & Mid(sInputHex, i * 2 + 1, 2))
        Next

        Return aBytes

    End Function

    Friend Function cv_BytesFromString(ByRef strInput As String) As Byte()
        ' Converts string <strInput> of ascii chars to array of bytes
        ' str may contain chars of any value between 0 and 255.
        ' E.g. strInput="abc." will return array {&H61, &H62, &H63, &H2E}
        Dim i As Integer
        Dim M As Integer
        Dim aBytes() As Byte

        M = Len(strInput)
        ReDim aBytes(M - 1)

        For i = 0 To M - 1
            aBytes(i) = Asc(Mid(strInput, i + 1, 1))
        Next

        Return aBytes

    End Function

    Friend Function cv_WordsFromHex(ByVal sHex As String) As Integer()
        ' Converts string <sHex> with hex values into array of words (long ints)
        ' E.g. "fedcba9876543210" will be converted into {&HFEDCBA98, &H76543210}
        Const ncLEN As Short = 8
        Dim i As Integer
        Dim nWords As Integer
        Dim aWords() As Integer

        nWords = Len(sHex) \ ncLEN
        ReDim aWords(nWords - 1)
        For i = 0 To nWords - 1
            aWords(i) = Val("&H" & Mid(sHex, i * ncLEN + 1, ncLEN))
        Next

        'UPGRADE_WARNING: Couldn't resolve default property of object cv_WordsFromHex. Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
        Return aWords

    End Function

    Friend Function cv_HexFromWords(ByRef aWords As Object) As String
        ' Converts array of words (Longs) into a hex string
        ' E.g. {&HFEDCBA98, &H76543210} will be converted to "FEDCBA9876543210"
        Const ncLEN As Short = 8
        Dim i As Integer
        Dim nWords As Integer
        Dim sHex As String = Nothing
        Dim iIndex As Integer

        If Not IsArray(aWords) Then
            Return ""
            Exit Function
        End If

        nWords = UBound(aWords) - LBound(aWords) + 1
        cv_HexFromWords = New String(" ", nWords * ncLEN)
        iIndex = 0
        For i = 0 To nWords - 1
            'UPGRADE_WARNING: Couldn't resolve default property of object aWords(). Click for more: 'ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
            sHex = Hex(aWords(i))
            sHex &= New String("0", ncLEN - Len(sHex))
            Mid(cv_HexFromWords, iIndex + 1, ncLEN) = sHex
            iIndex = iIndex + ncLEN
        Next
        Return sHex
    End Function

    Friend Function cv_HexFromBytes(ByRef aBytes() As Byte) As String
        ' Returns hex string from array of bytes
        ' E.g. aBytes() = {&HFE, &HDC, &H80} will return "FEDC80"
        Dim i As Integer
        Dim iIndex As Integer

        cv_HexFromBytes = New String(" ", (UBound(aBytes) - LBound(aBytes) + 1) * 2)
        iIndex = 0
        For i = LBound(aBytes) To UBound(aBytes)
            Mid(cv_HexFromBytes, iIndex + 1, 2) = HexFromByte(aBytes(i))
            iIndex = iIndex + 2
        Next

    End Function
    Friend Function cv_HexFromBytesSpace(ByRef aBytes() As Byte) As String
        ' Returns hex string from array of bytes
        ' E.g. aBytes() = {&HFE, &HDC, &H80} will return "FEDC80"
        Dim i As Integer
        Dim iIndex As Integer

        cv_HexFromBytesSpace = New String(" ", (UBound(aBytes) - LBound(aBytes) + 1) * 3)
        iIndex = 0
        For i = LBound(aBytes) To UBound(aBytes)
            Mid(cv_HexFromBytesSpace, iIndex + 1, 2) = HexFromByte(aBytes(i))
            iIndex = iIndex + 3
        Next
    End Function

    Friend Function cv_arrayFromString(ByRef str As String) As String()
        Dim f_str() As String = str.Split(",")
        Return f_str
    End Function

    Friend Function cv_StrFromBytes(ByRef aBytes() As Byte) As String
        ' Returns hex string from array of bytes
        ' E.g. aBytes() = {&HFE, &HDC, &H80} will return "FEDC80"
        Dim retStr As String = ""

        For Each by As Byte In aBytes
            retStr &= " " & Hex(by)
        Next
        Return retStr
    End Function
    Friend Function cv_StringFromBytes(ByRef aBytes() As Byte) As String
        ' Returns hex string from array of bytes
        ' E.g. aBytes() = {&HFE, &HDC, &H80} will return "FEDC80"
        Dim retStr As String = ""

        For Each by As Byte In aBytes
            retStr &= Chr(by)
        Next
        Return retStr
    End Function
    Friend Function cv_StringFromBytes(ByRef aBytes() As Byte, ByVal stIndex As UInt32, ByVal length As UInt32) As String
        Dim retStr As String = ""
        For i As UInt32 = stIndex To stIndex + length
            If aBytes(i) = 0 Then Exit For
            retStr &= Chr(aBytes(i))
        Next
        Return retStr
    End Function

    Friend Function cv_HexFromString(ByRef str_Renamed As String) As String
        ' Converts string <str> of ascii chars to string in hex format
        ' str may contain chars of any value between 0 and 255.
        ' E.g. "abc." will be converted to "6162632E"
        Dim byt As Byte
        Dim i As Integer
        Dim n As Integer
        Dim iIndex As Integer
        Dim sHex As String

        n = Len(str_Renamed)
        sHex = New String(" ", n * 2)
        iIndex = 0
        For i = 1 To n
            byt = CByte(Asc(Mid(str_Renamed, i, 1)) And &HFFS)
            Mid(sHex, iIndex + 1, 2) = HexFromByte(byt)
            iIndex = iIndex + 2
        Next
        cv_HexFromString = sHex

    End Function

    Friend Function cv_StringFromHex(ByRef strHex As String) As String
        ' Converts string <strHex> in hex format to string of ascii chars
        ' with value between 0 and 255.
        ' E.g. "6162632E" will be converted to "abc."
        Dim i As Short
        Dim nBytes As Short

        nBytes = Len(strHex) \ 2
        cv_StringFromHex = New String(" ", nBytes)
        For i = 0 To nBytes - 1
            Mid(cv_StringFromHex, i + 1, 1) = Chr(Val("&H" & Mid(strHex, i * 2 + 1, 2)))
        Next

    End Function

    Friend Function cv_GetHexByte(ByVal sInputHex As String, ByRef iIndex As Integer) As Byte
        ' Extracts iIndex'th byte from hex string (starting at 1)
        ' E.g. cv_GetHexByte("fecdba98", 3) will return &HBA
        Dim i As Integer
        i = 2 * iIndex
        If i > Len(sInputHex) Or i <= 0 Then
            cv_GetHexByte = 0
        Else
            cv_GetHexByte = Val("&H" & Mid(sInputHex, i - 1, 2))
        End If

    End Function

    Friend Function RandHexByte() As String
        '   Returns a random byte as a 2-digit hex string
        Static stbInit As Boolean
        If Not stbInit Then
            Randomize()
            stbInit = True
        End If

        RandHexByte = HexFromByte(CByte((Rnd() * 256) And &HFFS))
    End Function

    Private Function ChrFromByte(ByVal x As Object) As String
        ChrFromByte = Chr(x)
    End Function
    Public Function HexFromByte(ByVal x As Object) As String
        x = x And &HFFS
        If x < 16 Then
            HexFromByte = "0" & Hex(x)
        Else
            HexFromByte = Hex(x)
        End If
    End Function

End Module